package com.lqwu.manymanythumb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lqwu.manymanythumb.common.ErrorCode;
import com.lqwu.manymanythumb.constant.ThumbConstant;
import com.lqwu.manymanythumb.exception.BusinessException;
import com.lqwu.manymanythumb.exception.ThrowUtils;
import com.lqwu.manymanythumb.model.entry.Blog;
import com.lqwu.manymanythumb.model.entry.Thumb;
import com.lqwu.manymanythumb.model.entry.User;
import com.lqwu.manymanythumb.service.BlogService;
import com.lqwu.manymanythumb.service.ThumbService;
import com.lqwu.manymanythumb.mapper.ThumbMapper;
import com.lqwu.manymanythumb.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

/**
* @author 伍立权
* @description 针对表【thumb】的数据库操作Service实现
* @createDate 2025-05-18 23:46:31
*/
@Service("thumbServiceDB")
@RequiredArgsConstructor
public class ThumbServiceImpl extends ServiceImpl<ThumbMapper, Thumb>
    implements ThumbService{
    @Resource
    private UserService userService;
    @Resource
    @Lazy
    private BlogService blogService;
    //编程式事务
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 点赞
     * @param blogId
     * @param request
     * @return
     */
    @Override
    public boolean doThumb(Long blogId, HttpServletRequest request) {
        // 获取博客详情
        Blog blog = blogService.getById(blogId);
        // 获取当前用户
        User loginUser = userService.getLoginUser(request);
        // 根据用户id加同步锁
        synchronized (loginUser.getId().toString().intern()){
            // 编程式事务
            return transactionTemplate.execute(status -> {
                // 判断用户是否一点赞 (原数据库)
//                LambdaQueryWrapper<Thumb> queryWrapper = new LambdaQueryWrapper<>();
//                queryWrapper.eq(Thumb::getUserId, loginUser.getId())
//                        .eq(Thumb::getBlogId, blogId);
//                Thumb hasThumb = this.getOne(queryWrapper);
                boolean hasThumb = hasThumb(blogId, loginUser.getId());
                if (hasThumb){
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "不能重复点赞");
                }
                // 博客点赞数加一
                blog.setThumbCount(blog.getThumbCount() + 1);
                boolean update = blogService.updateById(blog);
                ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "点赞更新博客时失败");
                // 添加点赞记录
                Thumb thumb = new Thumb();
                thumb.setBlogId(blogId);
                thumb.setUserId(loginUser.getId());
                boolean save = this.save(thumb);
                ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "点赞添加记录时失败");
                // 添加到 Redis 中
                if (update && save){
                    redisTemplate.opsForHash().put(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId().toString(), blogId.toString(), thumb.getId());
                }
                return update && save;
            });
        }
    }

    /**
     * 判断用户是否已经点赞（从 Redis 中）
     * @param blogId
     * @param userId
     * @return
     */
    @Override
    public boolean hasThumb(Long blogId, Long userId) {
        return redisTemplate.opsForHash().hasKey(ThumbConstant.USER_THUMB_KEY_PREFIX + blogId, userId.toString());
    }

    /**
     * 取消点赞
     * @param blogId
     * @param request
     * @return
     */
    @Override
    public boolean cancelThumb(Long blogId, HttpServletRequest request) {
        // 获取博客详情
        Blog blog = blogService.getById(blogId);
        // 获取当前用户
        User loginUser = userService.getLoginUser(request);
        // 根据用户id加同步锁
        synchronized (loginUser.getId().toString().intern()){
            // 编程式事务
            return transactionTemplate.execute(status -> {
                // 判断用户是否一点赞
//                LambdaQueryWrapper<Thumb> queryWrapper = new LambdaQueryWrapper<>();
//                queryWrapper.eq(Thumb::getUserId, loginUser.getId())
//                        .eq(Thumb::getBlogId, blogId);
//                Thumb hasThumb = this.getOne(queryWrapper);
                Object thumbIdObj = redisTemplate.opsForHash().get(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId().toString(), blogId.toString());
                if (thumbIdObj == null) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户未点赞点赞");
                }
                Long thumbId = Long.valueOf(thumbIdObj.toString());
                // 博客点赞数减一
                blog.setThumbCount(blog.getThumbCount() - 1);
                boolean update = blogService.updateById(blog);
                ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "取消点赞更新博客时失败");
                // 删除点赞记录
                boolean remove = this.removeById(thumbId);
                ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "取消点赞添加记录时失败");
                // 删除 Redis 中的点赞记录
                if (update && remove){
                    redisTemplate.opsForHash().delete(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId().toString(), blogId.toString());
                }
                return update && remove;
            });
        }
    }
}




